package com.epam.web_project.bank.filters;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.epam.web_project.bank.command.CommandManager;
import com.epam.web_project.bank.entity.Customer;
import com.epam.web_project.bank.util.AppPropertiesLoader;

public class CheckUserLoggedInFilter implements Filter {
	private static Logger logger = Logger
			.getLogger(CheckUserLoggedInFilter.class);
	private static AppPropertiesLoader props = AppPropertiesLoader
			.getInstance();
	private static CommandManager commandManager = CommandManager.getInstance();
	private List<String> adminCommands = new ArrayList<String>();
	private List<String> approvedUserCommands = new ArrayList<String>();
	private List<String> unapprovedUserCommands = new ArrayList<String>();
	private List<String> tempUserCommands = new ArrayList<String>();
	private List<String> anyUserCommands = new ArrayList<String>();

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		anyUserCommands.add("login");
		anyUserCommands.add("register");
		anyUserCommands.add("recoverPass");
		anyUserCommands.add("logout");
		anyUserCommands.add("onMain");
		tempUserCommands.addAll(anyUserCommands);
		tempUserCommands.add("answer");
		tempUserCommands.add("changePass");
		unapprovedUserCommands.addAll(tempUserCommands);
		unapprovedUserCommands.add("cardRequest");
		unapprovedUserCommands.add("showUnapprovedCommand");
		unapprovedUserCommands.add("showCardRequestCommand");
		approvedUserCommands.addAll(unapprovedUserCommands);
		approvedUserCommands.add("showMainCommand");
		approvedUserCommands.add("showTransferCommand");
		approvedUserCommands.add("sendAccountId");
		approvedUserCommands.add("transfer");
		approvedUserCommands.add("block");
		approvedUserCommands.add("history");
		adminCommands.addAll(approvedUserCommands);
		adminCommands.add("showAdminMainCommand");
		adminCommands.add("showAccForm");
		adminCommands.add("createAccount");
		adminCommands.add("showUserInfo");
		adminCommands.add("approveUser");
		adminCommands.add("showWorkingAccountsCommand");
		adminCommands.add("unblock");
		adminCommands.add("showPutMoneyPage");
		adminCommands.add("putMoney");
		adminCommands.add("markWorkingAccountDeleted");
		adminCommands.add("markUnapprovedAccountDeleted");
		adminCommands.add("markUnapprovedUserDeleted");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		request.setCharacterEncoding ("UTF-8");
		HttpSession session = httpRequest.getSession();
		String action = httpRequest.getParameter("command");
		if(action==null) {
			chain.doFilter(request, response);
			return;
		}
		Customer customer = (Customer)session.getAttribute("customer");
		if(customer!=null && !customer.isDeleted()) {
			cusomerExists(httpRequest, response, chain, customer, action);
		} else if (session.getAttribute("customerTemp")!=null) { 
			//temp customer - password recovery
			if (action!=null && tempUserCommands.contains(action)) {
				chain.doFilter(request, response);
				return;
			} else {
				goToLoginPage(httpRequest, httpResponse);
				return;
			}
		} else { 
			//anyone else
			if(action!=null && anyUserCommands.contains(action)) {
				chain.doFilter(request, response);
				return;
			} else {
				goToLoginPage(httpRequest, httpResponse);
			}
			
		}
	}
	
	private void cusomerExists(HttpServletRequest httpRequest, ServletResponse 
			response,FilterChain chain,Customer customer, String action) 
					throws IOException, ServletException {
		String role=customer.getRole();
		if ("admin".equals(role)) { //user is admin
			chain.doFilter(httpRequest, response);
			return;
		} else if ("customer".equals(role) && !customer.isOnApproval()) {
			//user is an approved customer
			if(approvedUserCommands.contains(action)) {
				chain.doFilter(httpRequest, response);
				return;
			} else {
				goToLoginPage(httpRequest, response);
				return;
			}
		} else if ("customer".equals(role) && customer.isOnApproval()) {
			//user is an unapproved customer 
			if(unapprovedUserCommands.contains(action)) {
				chain.doFilter(httpRequest, response);
				return;
			} else {
				goToLoginPage(httpRequest, response);
				return;
			}
		}
	}

	@Override
	public void destroy() {
	}


	private void goToLoginPage(HttpServletRequest httpRequest,
			ServletResponse response) {
		AppPropertiesLoader props = AppPropertiesLoader.getInstance();
		try {
			((HttpServletResponse) response).sendRedirect(props.getProperty("login_page"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		/*RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(props
				.getProperty("login_page"));
		try {
			dispatcher.forward(httpRequest, response);
		} catch (ServletException e) {
			logger.error(e);
		} catch (IOException e) {
			logger.error(e);
		}*/
	}

}
